﻿using System;
using System.Data.Objects;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Collections;

namespace Pharmacy.Data
{
    /// <summary>
    /// Provides interface for an object context.
    /// </summary>
    public interface IObjectContext : IDisposable
    {
        /// <summary>
        /// Gets date time on the server.
        /// </summary>
        DateTime GetCurrentDateTime();

        /// <summary>
        /// UserName For Audit
        /// </summary>
        string UserName { get; set; }

        /// <summary>
        /// Creates new object context from existing context.
        /// </summary>
        IObjectContext CreateNew(bool withNewConnection= true);
        /// <summary>
        /// Exec Command On DataSource
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="command"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        IEnumerable<T> ExecCommand<T>(string command, params object[] parameters);
        /// <summary>
        /// Exec Command On DataSource
        /// </summary>
        /// <param name="command"></param>
        /// <param name="parameters"></param>
        void ExecCommand(string command, params object[] parameters);
        /// <summary>
        /// Only for internal using
        /// Gets or creates new object set of given object type.
        /// </summary>
        IObjectSet<T> CreateObjectSet<T>() where T : class;
        /// <summary>
        /// Only for internal using
        /// Gets or creates new object set of given object type.
        /// </summary>
        IObjectSet<T> CreateObjectSet<T>(MergeOption mergeOption) where T : class;
        /// <summary>
        /// Attach And Set Modify Property
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="properties"></param>
        void AttachAsModify<T>(T entity, params Expression<Func<T, object>>[] properties) where T : class;
        /// <summary>
        /// Saves changes to the data store.
        /// </summary>
        void SaveChanges();

        /// <summary>
        /// Update an object in object context with data from data source
        /// </summary>
        /// <param name="refreshMode"></param>
        /// <param name="entity"></param>
        void Reload(RefreshMode refreshMode, object entity);
        
        /// <summary>
        /// Update a collection of objects in object context with data from data source
        /// </summary>
        /// <typeparam name="T">type of entity</typeparam>
        /// <param name="refreshMode"></param>
        /// <param name="entity">object is needed to reload</param>
        void Reload(RefreshMode refreshMode, IEnumerable collection);        
    }
}
